<?php

namespace hunma\basic;

use app\common\Request;
use hunma\exception\ValidationException;
use support\Log;
use think\Validate;

abstract class BaseController
{
    /**
     * 获取请求参数
     *
     * @param string|array $keys 单个键或关联数组（键为参数名，值为默认值）
     * @param mixed $default 默认值（可选，仅在 $keys 为字符串时有效）
     * @return mixed|array
     */
    protected function getParam($keys, $default = null)
    {
        // 如果是单个键
        if (is_string($keys)) {
            return request()->get($keys, $default);
        }

        $result = [];
        if (is_array($keys)) {
            foreach ($keys as $key => $value) {
                // 如果是纯键名数组（键为数字索引）
                if (is_int($key)) {
                    $paramKey = $value; // 键名
                    $paramDefault = $default; // 使用统一的默认值
                } else {
                    // 如果是关联数组（键为字符串）
                    $paramKey = $key; // 键名
                    $paramDefault = $value; // 使用指定的默认值
                }

                // 获取请求参数
                $result[$paramKey] = request()->get($paramKey, $paramDefault);
            }
            return $result;
        }

        return $default;
    }

    /**
     * 获取所有请求参数
     *
     * @param Request $request 请求对象
     * @return array
     */
    protected function getAllParams(): array
    {
        return request()->all();
    }

    /**
     * 获取分页参数
     *
     * @return array [当前页, 每页数量]
     */
    protected function getPage(): array
    {
        $page = (int)$this->getParam('page', 1);
        $perPage = (int)$this->getParam('per_page', 10);

        return [$page, $perPage];
    }


    /**
     * 将简化格式的规则转换为验证器所需的格式
     * 注意：一次请求避免多次调用，影响性能，每次都是获取所有的参数后做验证
     *
     * @param array $rules 简化格式的规则
     * @return array [rules, messages]
     */
    protected function parseValidationRules(array $rules): string
    {
        $parsedRules = [];
        $parsedMessages = [];

        foreach ($rules as $rule) {
            $field = $rule[0];       // 字段名称
            $ruleStr = $rule[1];     // 验证规则
            $message = $rule[2] ?? ''; // 错误提示信息

            // 如果字段的规则已存在，追加新的规则
            if (isset($parsedRules[$field])) {
                $parsedRules[$field] .= '|' . $ruleStr;
            } else {
                $parsedRules[$field] = $ruleStr;
            }

            // 解析规则中的每个部分，生成对应的错误消息
            $ruleParts = explode('|', $ruleStr);
            foreach ($ruleParts as $part) {
                $ruleName = explode(':', $part)[0]; // 去掉参数部分
                $parsedMessages["$field.$ruleName"] = $message;
            }
        }

        $validation = $this->validate($this->getAllParams(), $parsedRules, $parsedMessages);

        if ($validation !== true) {
            throw new ValidationException((string)$validation);
        }

        return $validation;
    }

    /**
     * 验证请求参数
     *
     * @param array $data 待验证的数据
     * @param array $rules 验证规则
     * @param array $messages 自定义错误消息（可选）
     * @return array|true 返回验证错误信息数组，如果验证通过则返回 true
     */
    protected function validate(array $data, array $rules, array $messages = [])
    {
        // 实例化验证器
        $validator = new Validate();

        // 设置验证规则
        $validator->rule($rules);

        // 设置自定义错误消息
        if (!empty($messages)) {
            $validator->message($messages);
        }

        // 执行验证
        if (!$validator->check($data)) {
            return $validator->getError();
        }

        return true;
    }


    /**
     * 记录日志
     *
     * @param string $message
     * @param array $context
     */
    protected function log(string $message, array $context = []): void
    {
        // 这里可以使用 webman 的日志组件或其他日志库
        Log::info($message, $context);
    }
}
